#pragma once
#include "al_IAbilityInstance.h"
#include "al_IAbility.h"
//#include "al_IAbilityTarget.h"
#include <string>

namespace	ability_types
{

/**
Class:		BasicAbility
Purpose:	Implementation of IAbility and IAbilityInstance,
			Provides basic functionality for abilities
			Provides easy over-riding for ability templates
Usage:		Extend, provide a constructor and overide 
			condition(){return true;} and action members.
**/
class BasicAbility : public ability_core::IAbilityInstance, public ability_core::IAbility
{
	//IAbilityInstance Fields
	ability::IAbilityOwner *	_ownerPtr;
	int _amount;

	//IAbility Fields
	int _mpCost;
	int _cooldown;
	std::string _name;
	
	//BasicAbility Fields
	long int _cooldownStartTime;
	
public:
	BasicAbility(std::string name,ability::IAbilityOwner * ownerPtr, int amount, int mpCost, int cooldown)
	{
		_amount = amount;		//IAbilityInstance
		_ownerPtr = ownerPtr;

		_cooldown  = cooldown;	//IAbility
		_mpCost = mpCost;
		_name = name;

		_cooldownStartTime = -1;//BasicAbility
	}
	~BasicAbility(){}
	//IAbilityInstance - Members
	int			IAbilityInstance::		getAmount(){return _amount;}
	void		IAbilityInstance::		setAmount(int amount){_amount = amount;}
	void		IAbilityInstance::		selectTarget(void* ePtr){std::cout << "Warning - Basic ability cannot select target" << std::endl;}
	bool		IAbilityInstance::		isCooledDown(long int currentTime)
	{
		//std::cout << currentTime << " > = " << _cooldown << " + " << _cooldownStartTime << std::endl;
		return (currentTime >= _cooldown+ _cooldownStartTime);
	}
	void		IAbilityInstance::		setCooldown	(long int startTime){_cooldownStartTime = startTime;}
	ability::IAbilityOwner *	IAbilityInstance::	getOwner(){return _ownerPtr;}
	bool		IAbilityInstance::		isEnabled(long int currentTime)
	{
		bool hasCooledDown = isCooledDown(currentTime);
		bool hasMana = getOwner()->get_mp() >= getMpCost();//getCurrentStats()->getMp()

		if(!hasCooledDown)	{std::cout << "Ability hasn't cooled down yet - Cannot cast "<<getName() <<std::endl;}
		if(!hasMana)		{std::cout << "Out of Mana - Cannot cast "<<getName() <<std::endl;}

		return (hasCooledDown && hasMana);
	}
	void IAbilityInstance::				use(long int currentTime)
	{
		if (isEnabled(currentTime))
		{
			std::cout <<"UID "<< /*getOwner()->get_name() */ "" <<" used ability "<<getName() << std::endl;

			if (condition())
			action();

			setCooldown(currentTime);
			_ownerPtr->add_mp(-_mpCost,99999999);
		}
	}

	//IAbility - Members
	int			IAbility::	getMpCost(){return _mpCost;}
	int			IAbility::	getCooldownTime(){return _cooldown;}
	void		IAbility::	setName(std::string s){_name = s;}
	std::string IAbility::	getName(){return _name;}
	virtual bool IAbility::	condition() = 0;
	virtual void IAbility::	action() = 0;
};

}